/*
	navi-tech 1- Eternal Team(c) 2012
	Md2 File Loader and Renderer.
	
	Note, data commented with "(garbage)" denotes
	the data was required for Id Tech 2, but not
	for navi-tech 1 and is therefore disposable. 
*/

#include "../Hdr/Md2Model.h"
#include "../Hdr/DbgLog.h"
#include "../Hdr/Globals.h"
#include <malloc.h>
#include <iostream>
#include <SDL/SDL_opengl.h>

Eternal::Scene::Md2Model::Md2Model()
{
	
}

Eternal::Scene::Md2Model::~Md2Model()
{
	
}

void Eternal::Scene::Md2Model::Load(const char *file)
{
	DbgLog *Dbg = DbgLog::GetInstance();
	Dbg->Print("Loading Md2 file");

	/* For loops */
	unsigned short i, j;

	FILE *ifile = fopen(file, "rb");
	if ( ifile == NULL )	{
		Dbg->Print("Md2 file '%s' cannot be found!", file);
		return;
	}
	
	/* Load the header */
	md2_header_t header;
	fread(&header, sizeof(md2_header_t), 1, ifile);
	
	/* Allocate required data */
	TexCoords = new md2_st_t[header.i_numst];
	Frames = new md2_frame_t[header.i_numframes];
	Triangles = new md2_triangle_t[header.i_numtriangles];
	
	/* Check it has the Md2 signiture (IDP2) */
	if ( header.ident[0] != 'I' || header.ident[1] != 'D'
		|| header.ident[2] != 'P' || header.ident[3] != '2' )	{
		Dbg->Print("Invalid or corrupt Md2 file %s", header.ident);
		return;
	}
	Dbg->Print("Md2 signiture was found...");
	
	/* Version 8 is supported */
	if ( header.i_ver != 8 )	{
		Dbg->Print("Invalid version, 8 required %i given", header.i_ver);
		return;
	}
	Dbg->Print("Compatible version was given...");

	
	/* Load whatever skins are present */
	fseek(ifile, header.i_ofskins, SEEK_SET);
	for ( i = 0;i < header.i_numskins;i++ )
	{
		fread(&c_Buffer, 64, 1, ifile);
	}
	
	/* Load the ST texture coords */
	fseek(ifile, header.i_ofst, SEEK_SET);
	for ( i = 0;i < header.i_numst;i++ )
	{
		fread(&TexCoords[i], sizeof(md2_st_t), 1, ifile);
	}
	
	/* Load the triangles */
	fseek(ifile, header.i_oftris, SEEK_SET);
	for ( i = 0;i < header.i_numtriangles;i++ )
	{
		fread(&Triangles[i].vert_indices, sizeof(short) * 3, 1, ifile);
		fread(&Triangles[i].tex_indices, sizeof(short) * 3, 1, ifile);
	}
	
	/* Load the frames */
	fseek(ifile, header.i_offrames, SEEK_SET);
	for ( i = 0;i < header.i_numframes;i++ )
	{
		fread(&Frames[i].Translate[0], sizeof(float), 1, ifile);
		fread(&Frames[i].Translate[1], sizeof(float), 1, ifile);
		fread(&Frames[i].Translate[2], sizeof(float), 1, ifile);
		
		fread(&Frames[i].Scale[0], sizeof(float), 1, ifile);
		fread(&Frames[i].Scale[1], sizeof(float), 1, ifile);
		fread(&Frames[i].Scale[2], sizeof(float), 1, ifile);
		
		fread(&Frames[i].name, 16, 1, ifile);
		std::cout << Frames[i].name << std::endl;
		Frames[i].Verts = new md2_vertex_t[header.i_numverts];
		for ( j = 0;j < header.i_numverts;j++ )
		{
			fread(&Frames[i].Verts[j].v, 3, 1, ifile);			
			char c; fread(&c, 1, 1, ifile);
		}
	}
	
	/* Copy data from the header, needed later */
	i_NumTriangles = (unsigned)header.i_numtriangles;
	i_NumVerts = (unsigned)header.i_numverts;
	
	/* Output file details */
	Dbg->Print("Verts: %i\nTriangles: %i\nFrames: %i", header.i_numverts, header.i_numtriangles, header.i_numframes);
	Dbg->Print("Skins: %i\nTexture Coords: %i", header.i_numskins, header.i_numst);
	
	fclose(ifile);
}

void Eternal::Scene::Md2Model::Render()
{
	glDisableClientState(GL_VERTEX_ARRAY);
	
	glColor3f(1,1,1);
	glRotatef(90, 1, 0, 0);
	glScalef(0.5, 0.5, 0.5);
	glBegin(GL_TRIANGLES);
	for ( unsigned i = 0;i < i_NumTriangles;i++ )
	{	
			for ( unsigned j = 0;j < 3;j++ )
			{
				glVertex3f(
					Frames[0].Translate[0] 
					+ ((float)Frames[0].Verts[Triangles[i].vert_indices[j]].v[0]
					* Frames[0].Scale[0]),
					
					Frames[0].Translate[1] 
					+ ((float)Frames[0].Verts[Triangles[i].vert_indices[j]].v[1]
					* Frames[0].Scale[1]),
					
					Frames[0].Translate[2] 
					+ ((float)Frames[0].Verts[Triangles[i].vert_indices[j]].v[2]
					* Frames[0].Scale[2]));
			}
					
	}
	glEnd();
}